#include "../include/LogicHandler.h"
#include <nlohmann/json.hpp>
#include <iostream>
#include "../include/userCenterRpc.h"
#include "../include/statusServe_rpc.h"

void LogicHandler::handler_get(const std::shared_ptr<httpConnection> &con)
{
    //解析url
    con->prase_get_url();

    //通过判断req里的路由，判断是否能找到对应的处理函数

    if(_get_handlers.count(con->_get_url)){
        //如果存在
        _get_handlers[con->_get_url](con);
        return;
    }

    con->response_404();
}

void LogicHandler::handler_post( const std::shared_ptr<httpConnection> & con)
{

    //未完善
    
    //通过判断req里的路由，判断是否能找到对应的处理函数
    std::cout<<"此次post请求url为："<<con->_request.target()<<std::endl;
    if(_post_handlers.count(con->_request.target())){
        //如果存在
        _post_handlers[con->_request.target()](con);
        return;
    }
    con->response_404();


}

LogicHandler::LogicHandler(){
    init_get_handlers();
    init_post_handlers();
}

void LogicHandler::init_get_handlers()
{
    //就是测试用
    _get_handlers.insert(std::make_pair("/test_get",[](const std::shared_ptr<httpConnection> & con){
        con->_response.version(con->_request.version());
        con->_response.result(http::status::ok);

        con->_response.keep_alive(false);

        con->_response.set(http::field::content_type,"text/plain");
        boost::beast::ostream(con->_response.body())<<"get request conplete!!!\n";
        for(auto it=con->url_key_value.begin();it!=con->url_key_value.end();++it){
            boost::beast::ostream(con->_response.body())<<"key: "<<it->first<<" value: "<<it->second<<"\n";
        }
        con->_response.prepare_payload();
        http::async_write(con->_socket,con->_response,[con](boost::beast::error_code, ::std::size_t){
            std::cout<<"成功发送一个 ok 响应"<<std::endl;
        });
    }));

}

void LogicHandler::init_post_handlers()
{
    //注册各种路由

    _post_handlers.insert(std::make_pair("/get_varifyCode",[this](const std::shared_ptr<httpConnection> &con){
        this->doing_post_get_varifyCode(con);
    }));

    _post_handlers.insert(std::make_pair("/register_user",[this](const std::shared_ptr<httpConnection> &con){
        this->doing_post_register_user(con);
    }));

    _post_handlers.insert(std::make_pair("/reset_passwd",[this](const std::shared_ptr<httpConnection> &con){
        this->doing_post_reset_passwd(con);
    }));

    _post_handlers.insert(std::make_pair("/login",[this](const std::shared_ptr<httpConnection> &con){
        this->doing_post_login(con);
    }));

    



}

//响应获取验证码的请求
void LogicHandler::doing_post_get_varifyCode(const std::shared_ptr<httpConnection> &con)
{
    //验证码请求
    nlohmann::json req_json;
    nlohmann::json response_json;
    //响应行
    con->_response.version(con->_request.version());
    con->_response.result(http::status::ok);
    //响应头
    con->_response.keep_alive(false);
    con->_response.set(http::field::content_type,"/application/json");

    try{
        //反序列化body
        req_json=nlohmann::json::parse(boost::beast::buffers_to_string(con->_request.body().data())) ;
        
    }catch(const std::exception& e){
        std::cout<<"json解析错误："<<e.what()<<std::endl;
        
        //响应体
        response_json["result"]=false;
        response_json["info"]="json解析错误";
        //序列化后写入body
        boost::beast::ostream(con->_response.body())<<response_json.dump();
        con->_response.prepare_payload();
        http::async_write(con->_socket,con->_response,[con](boost::beast::error_code ec,std::size_t size){
            if(ec){
                std::cout<<"异步写出错了："<<ec.what()<<std::endl;
                return;
            }
            std::cout<<"成功回应一个post请求"<<std::endl;
        });
        return;
    }
    //解析成功
    //std::cout<<"邮箱："<<req_json["email"]<<"发来请求"<<std::endl;

    response_json["email"]=req_json["email"];
    //这里其实还要做一些生成验证码的操作------------------------------
    message::resGetVarify *res_msg=userCenterRpc::get_instance()->get_varify_code(req_json["email"].get<std::string>());
    if(res_msg->result()==false){
        response_json["result"]=false;
        //出现错误才会有提示信息
        response_json["info"]="当前服务不可用";
        std::cout<<"邮箱获取失败"<<std::endl;
    }else{
        response_json["result"]=true;
        response_json["code"]=res_msg->code();
        std::cout<<response_json["email"]<<"的验证码为："<<res_msg->code()<<std::endl;
    }
    delete res_msg; //这里进行析构

    boost::beast::ostream(con->_response.body())<<response_json.dump();
    con->_response.prepare_payload();
    http::async_write(con->_socket,con->_response,[con](boost::beast::error_code ec,std::size_t size){
        if(ec){
            std::cout<<"异步写出错了："<<ec.what()<<std::endl;
            return;
        }
        std::cout<<"成功回应一个post请求"<<std::endl;
    });

    
    

}

//响应注册请求
void LogicHandler::doing_post_register_user(const std::shared_ptr<httpConnection> &con)
{
    nlohmann::json req_json;
    nlohmann::json rps_json;

    //响应行与响应头
    con->_response.version(con->_request.version());
    con->_response.result(http::status::ok);

    con->_response.keep_alive(false);
    con->_response.set(http::field::content_type,"/application/json");

    try{
        req_json=nlohmann::json::parse(boost::beast::buffers_to_string(con->_request.body().data()));
    }catch(const std::exception &e){
        std::cout<<"/register_user/中json解析错误"<<std::endl;
        rps_json["result"]=false;
        rps_json["info"]="json解析错误";
        boost::beast::ostream(con->_response.body())<<rps_json.dump();
        con->_response.prepare_payload();    //自动计算长度并填充content_length字段
        http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
            if(ec){
                std::cout<<"异步写出错了："<<ec.what()<<std::endl;
                con->_response.clear();
                return;
            }else{
                std::cout<<"调试信息：成功响应一个注册请求"<<std::endl;
                con->_response.clear();
                return;
            }
        });
        return;
    }
    
    //将json解析好，然后进行注册的rpc调用
    std::string userName=req_json["userName"].get<std::string>();
    std::string email=req_json["email"].get<std::string>();
    std::string passwd=req_json["passwd"].get<std::string>();
    std::string authCode=req_json["authCode"].get<std::string>();
    //std::cout<<userName<<" "<<email<<" "<<passwd<<" "<<authCode<<std::endl;
    message::resRegisterUser* rpc_res=userCenterRpc::get_instance()->registerUser(userName,email,passwd,authCode);
    // if(rpc_res->result()==false){
    //     rps_json["result"]=rpc_res->result();
    //     rps_json["info"]="当前服务不可用";
    // }else{
    //     rps_json["result"]=rpc_res->result();
    //     rps_json["info"]=rpc_res->info();
    // }
    rps_json["result"]=rpc_res->result();
    rps_json["info"]=rpc_res->info();
    delete rpc_res;
    //写入返回即可
    boost::beast::ostream(con->_response.body())<<rps_json.dump();
    con->_response.prepare_payload();
    http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
        if(ec){
            std::cout<<"异步写出错了："<<ec.what()<<std::endl;
            con->_response.clear();
            return;
        }else{
            std::cout<<"调试信息：成功响应一个注册请求"<<std::endl;
            con->_response.clear();
            return;
        }
    });
}

//响应密码重置请求
void LogicHandler::doing_post_reset_passwd(const std::shared_ptr<httpConnection>& con){
    nlohmann::json req_json;    //将请求中的数据反序列化到这
    nlohmann::json  res_json;    //填充响应数据

    con->_response.version(con->_request.version());
    con->_response.result(http::status::ok);

    con->_response.set(http::field::content_type,"application/json");
    con->_response.keep_alive(false);
    
    //解析数据
    try{
        req_json=nlohmann::json::parse(boost::beast::buffers_to_string(con->_request.body().data()));
    }catch(const std::exception &e){
        std::cout<<"/reset_passwd/中json解析错误"<<std::endl;
        res_json["result"]=false;
        res_json["info"]="json解析错误";
        boost::beast::ostream(con->_response.body())<<res_json.dump();
        con->_response.prepare_payload();    //自动计算长度并填充content_length字段
        http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
            if(ec){
                std::cout<<"异步写出错了："<<ec.what()<<std::endl;
                con->_response.clear();
                return;
            }else{
                std::cout<<"调试信息：成功响应一个重置请求，不过报异常了"<<std::endl;
                con->_response.clear();
                return;
            }
        });
        return;
    }
    std::string email=req_json["email"].get<std::string>();
    std::string new_passwd=req_json["new_passwd"].get<std::string>();
    std::string authCode=req_json["varifyCode"].get<std::string>();

    message::resResetPasswd*res=userCenterRpc::get_instance()->reset_passwd(email,new_passwd,authCode);
    // if(res->result()==false){
    //     res_json["result"]=false;
    //     res_json["info"]="当前服务不可用";
    // }else{
    //     res_json["result"]=res->result();
    //     res_json["info"]=res->info();
    // }
    res_json["result"]=res->result();
    res_json["info"]=res->info();
    boost::beast::ostream(con->_response.body())<<res_json.dump();
    con->_response.prepare_payload();
    http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
        if(ec){
            std::cout<<"异步写出错了："<<ec.what()<<std::endl;
            con->_response.clear();
            return;
        }else{
            std::cout<<"调试信息：成功响应一个密码重置请求"<<std::endl;
            con->_response.clear();
            return;
        }
    });



}

//响应登陆请求
void LogicHandler::doing_post_login(const std::shared_ptr<httpConnection> &con)
{
    nlohmann::json req_json;
    nlohmann::json res_json;

    //简单设置响应头
    con->_response.version(con->_request.version());
    con->_response.result(http::status::ok);

    con->_response.set(http::field::content_type,"application/json");
    con->_response.keep_alive(false);

    //解析json
    try{
        req_json=nlohmann::json::parse(boost::beast::buffers_to_string(con->_request.body().data()));
    }catch(const std::exception &e){
        std::cout<<"/login/中json解析错误"<<std::endl;
        res_json["result"]=false;
        res_json["info"]="json解析错误";
        boost::beast::ostream(con->_response.body())<<res_json.dump();
        con->_response.prepare_payload();    //自动计算长度并填充content_length字段
        http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
            if(ec){
                std::cout<<"异步写出错了："<<ec.what()<<std::endl;
                con->_response.clear();
                return;
            }else{
                std::cout<<"调试信息：成功响应一个登陆请求，不过报异常了"<<std::endl;
                con->_response.clear();
                return;
            }
        });
        return;
    }

    std::string email=req_json["email"].get<std::string>();
    std::string passwd=req_json["passwd"].get<std::string>();
    message::resLogin *res=userCenterRpc::get_instance()->login(email,passwd);
    

    if(res->result()==false){
        //密码校验失败
        res_json["result"]=res->result();
        res_json["info"]="token校验失败";
    }else{
        //校验成功：这里考虑去从状态服务中获取可用chat_server
        message::resGetChatServerAddress *res_getChat=statusServer_rpc::get_instance()->get_chatServer_address(email);
        if(res_getChat->result()==false){
            //如果获取失败
            res_json["result"]=false;
            res_json["info"]="当前无可用服务";
        }else{
            res_json["result"]=true;
            res_json["info"]=res_getChat->info();
            res_json["port"]=res_getChat->port();
            res_json["host"]=res_getChat->host();
            res_json["token"]=res_getChat->token();
            res_json["user_name"]=res->info();  //当返回成功时，这个info就是user_name
            std::cout<<"发送的token为："<<res_getChat->token()<<std::endl;
        }
        delete res_getChat;
    }
    delete res;
   

    boost::beast::ostream(con->_response.body())<<res_json.dump();
    std::cout<<res_json.dump(4)<<std::endl;
    con->_response.prepare_payload();

    http::async_write(con->get_socket(),con->_response,[con](boost::beast::error_code ec,std::size_t size){
        if(ec){
            std::cout<<"异步写出错了："<<ec.what()<<std::endl;
            con->_response.clear();
            return;
        }else{
            std::cout<<"调试信息：成功响应一个登陆请求请求"<<std::endl;
            con->_response.clear();
            return;
        }
    });
    

}




